#include <iostream>
#include <string>
#include <functional>
#include <vector>
#include <time.h>
#include <unistd.h>
#include <pthread.h>

//编译这个文件：g++ pthread-backup.cc -lpthread


//pthread_t pthread_self(void):获取调用该函数的线程的id --> cout << pthread_self() << endl;

// std::string ToHex(pthread_t tid)
// {
//     char id[64];
//     snprintf(id,sizeof(id),"0x%lx",tid);
//     return id;
// }
// void *threadRoutine(void* arg)
// {
//     usleep(1000);
//     std::string name = static_cast<const char*>(arg);
//     int cnt = 5;
//     while(cnt--)
//     {
//         std::cout << "新线程正在运行，名字是：" << name << "线程id：" << ToHex(pthread_self()) << std::endl;
//         sleep(1);
//     }
//     return nullptr;//该线程终止（主线程仍然运行，进程不会终止）
//     //exit(13);//该线程终止（进程也随之终止）
//     //pthread_exit(nullptr);//使调用该函数的线程退出，不影响其他进程
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,threadRoutine,(void*)"thread-1");

//     std::cout << "主线程id：" << ToHex(pthread_self()) << std::endl;
//     sleep(10);

//     //线程也需要被等待，如果没有等待，会导致类似僵尸进程的问题（当然没有僵尸线程这样的说法）
//     int n = pthread_join(tid,nullptr);//这个函数阻塞等待线程的退出，并将退出结果返回
//     std::cout << "主线程完成，n：" << n << std::endl;
//     sleep(5);
//     return 0;
// }



// std::string ToHex(pthread_t tid)
// {
//     char id[64];
//     snprintf(id,sizeof(id),"0x%lx",tid);
//     return id;
// }
// void *threadRoutine(void* arg)
// {
//     usleep(1000);
//     std::string name = static_cast<const char*>(arg);
//     int cnt = 5;
//     while(cnt--)
//     {
//         std::cout << "新线程正在运行，名字是：" << name << ",线程id：" << ToHex(pthread_self()) << std::endl;
//         sleep(1);
//     }
    
//     //return (void*)"新线程结束";//整一个就是这个字符串常量的起始地址，虽然函数在栈区，但是这个是字符串常量，所以位置在常量区，函数结束不会被销毁
//     pthread_exit((void*)"新线程结束");//将括号中的内容返回
//     //pthread_exit((void*)10);
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,threadRoutine,(void*)"thread-1");

//     std::cout << "主线程id：" << ToHex(pthread_self()) << std::endl;

//     //线程也需要被等待，如果没有等待，会导致类似僵尸进程的问题（当然没有僵尸线程这样的说法）
//     void* ret = nullptr;//void不能定义变量类型，因为这表示长度不确定，但是void*是指针，字节大小为4/8
//     int n = pthread_join(tid,&ret);//这个函数阻塞等待线程的退出，并将线程退出结果返回（注意第二个参数的类型是void**）
//     //注意是新进程正常退出才会收到返回结果，如果中间就出现异常导致新线程没运行完也没关系，因为可能整个进程都跟着结束掉了，看进程的退出信息即可
//     std::cout << "主线程完成，n：" << n << std::endl;
//     std::cout << "主线程获得新线程的返回值为：" << (const char*)ret <<endl;
//     //std::cout << "主线程获得新线程的返回值为：" << (long long int)ret <<endl;//注意上面返回10，这里强转成int会报错，因为64位机器上指针的大小为8字节，而int只有4字节
//     return 0;
// }



// class ThreadReturn
// {
// public:
//     ThreadReturn(pthread_t id, const std::string &info, int code)
//         : id_(id), info_(info), code_(code)
//     {
//     }

// public:
//     pthread_t id_;
//     std::string info_;
//     int code_;
// };
// std::string ToHex(pthread_t tid)
// {
//     char id[64];
//     snprintf(id,sizeof(id),"0x%lx",tid);
//     return id;
// }
// void *threadRoutine(void* arg)
// {
//     usleep(1000);
//     std::string name = static_cast<const char*>(arg);
//     int cnt = 5;
//     while(cnt--)
//     {
//         std::cout << "新线程正在运行，名字是：" << name << ",线程id：" << ToHex(pthread_self()) << std::endl;
//         sleep(1);
//     }
    
//     ThreadReturn* ret = new ThreadReturn(pthread_self(),"线程正常退出",10);//void*可以接受任意类型的参数，包括结构体和对象
//     return ret;
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid,nullptr,threadRoutine,(void*)"thread-1");

//     std::cout << "主线程id：" << ToHex(pthread_self()) << std::endl;

//     void* ret = nullptr;
//     int n = pthread_join(tid,&ret);
//     std::cout << "主线程完成，n：" << n << std::endl;

//     ThreadReturn* r = static_cast<ThreadReturn*>(ret);
//     std::cout << "主线程获得新线程的返回值为：" << r->code_ << "," << ToHex(r->id_) << "," << r->info_ << endl;
//     delete r;
//     return 0;
// }



// 把10组数据的任务，交给一个线程，让线程运行，运行完了，再把结果返回
// struct data//要计算的数据
// {
//     int x;
//     int y;
//     char op; // + - * /
// };

// struct res//计算结果
// {
//     int code;
//     int result;
// };

// class InAndOut
// {
// public:
//     int who;
//     std::vector<data> datas;
//     std::vector<res> results;
// }



// void *threadRoutine(void *arg)
// {
//     pthread_detach(pthread_self());//线程主动把自己设置为分离状态
//     int cnt = 5;
//     while (cnt--)
//     {
//         std::cout << "thread is running..." << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, (void *)"thread-1");
  
//     sleep(1);

//     // 线程是可以被设置为分离状态（就是线程之间不用再相互等待，你做你的事情，我做我的事情）的
//     // 线程模式默认是joinable的，也就是需要被等待，回收退出之后的资源

//     // pthread_detach(tid);//除了在threadRoutin函数中线程自己设置分离状态，还可以在main函数中由主线程给其他线程设置分离状态

//     int n = pthread_join(tid, nullptr); //返回值为22，说明了join失败，该新线程无需join，或者回收这个退出线程的资源失败了
//     //上面函数返回的是nullptr，pthread_join函数成功接收到之后应返回0（nullptr就是0）
//     std::cout << "主线程完成，" << " n: " << n << std::endl;
//     return 0;
// }



// void *threadRoutine(void *arg)
// {
//     int cnt = 5;
//     while (true)
//     {
//         std::cout << "thread is running..." << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }
// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, threadRoutine, (void *)"thread-1");
  
//     sleep(1);

//     //pthread_detach(tid);//分离之后可以被取消，但不能被join（返回值为22）

//     int n = pthread_cancel(tid);

//     std::cout << "主线程取消新线程成功," << " n: " << n << std::endl;

//     void *ret = nullptr;
//     n = pthread_join(tid, &ret);
//     std::cout << "主线程join完成，" << " n: " << n << " 新线程退出结果: " << (int64_t)ret << std::endl;
//     // #define PTHREAD_CANCELED ((void *) -1)：异常终止/被取消的线程返回值为-1
//     return 0;
// }



